package select;

import java.util.List;
import java.util.Map;

import neural.Individual;

public class Boltzmann extends UniversalRoulette {
	
	double T;
	
	double minT = 570;
	
	
	public Boltzmann(double T) {
		this.T = T;
	}
	
	@Override
	public void calculateFrequencies(
			Map<Individual, FitnessValues> fitnessMap, Double totalFitness,
			List<Individual> individuals) {
		Individual previous = null;
		double totalBoltzmann = 0;
		for(Individual individual: individuals){
			totalBoltzmann += Math.pow(Math.E, fitnessMap.get(individual).getFitness()/T);
		}
		for(Individual individual: individuals){
			Double aux = Math.pow(Math.E, fitnessMap.get(individual).getFitness()/T)/totalBoltzmann;
			fitnessMap.get(individual).setRelativeFrequency(aux);
			if(previous == null){
				fitnessMap.get(individual).setAcumulatedFrequency(aux);
			}else{
				Double acumulated = fitnessMap.get(previous).getAcumulatedFrequency();
				fitnessMap.get(individual).setAcumulatedFrequency(acumulated + aux);
			}
			previous = individual;
		}
		if(T>minT){
			T=T*0.9;
		}
		//System.out.println("T = " + T);
		
		double sum = 0;
		for(Individual ind: fitnessMap.keySet()){
			sum = sum + fitnessMap.get(ind).getRelativeFrequency();
			//System.out.print("(" + ind.getFitness() + ":"+fitnessMap.get(ind).getRelativeFrequency() + ")");
		}
		//System.out.println();
		//System.out.println(sum);
		maxR = sum;
	}

	@Override
	public Double getRand() {
		return (Math.random() - (maxV + minV) / 2)
				* ((maxR - minR) / (maxV - minV)) + ((maxR + minR) / 2);
	}

}
